/**
 * Created by LiYang on 16-9-27 下午2:07.
 *
 */

package com.example.db.generate;

import android.content.ContentValues;

import com.example.db.DBSerializable;
import com.example.db.annotation.Column;
import com.example.db.annotation.ColumnMeta;
import com.example.db.annotation.TableMeta;
import com.example.db.utils.BeanUtil;
import com.example.db.utils.CommonUtil;
import com.example.db.utils.ObjectUtil;

import java.lang.reflect.Field;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

public class EntityGenerateHandler<T extends DBSerializable> implements GenerateHandler<T> {

    private final Map<String, Column> entityFields = new LinkedHashMap<String, Column>();
    private String TAG = "entityGenerateHandler";
    private String tableName;

    public EntityGenerateHandler(Class<T> klass) {
        initEntityTable(klass);
        initEntityFieldMap(klass);
    }

    private void initEntityTable(Class<T> klass) {
        if (klass.isAnnotationPresent(TableMeta.class)) {
            // 若已存在，则使用该注解中定义的表名
            TableMeta table = klass.getAnnotation(TableMeta.class);
            tableName = table.value();
        }
        if (ObjectUtil.isEmpty(tableName)) {
            // 若不存在，则将实体类名转换为下划线风格的表名
            tableName = CommonUtil.toUnderline(klass.getSimpleName());
        }
    }

    private void initEntityFieldMap(Class<T> klass) {
        // 获取并遍历该实体类中所有的字段
        Field[] fields = BeanUtil.getFields(klass);
        if (fields.length == 0) {
            return;
        }
        // 创建一个 fieldMap（用于存放列名与字段名的映射关系）
        for (Field field : fields) {
            ColumnMeta column = field.getAnnotation(ColumnMeta.class);
            if (column == null) {
                continue;
            }
            entityFields.put(field.getName(), new Column(field.getName(), column));
        }
    }

    /**
     * 生成表内列DLL
     *
     * @return dll
     */
    private String getColumnDDL() {
        StringBuilder build = new StringBuilder();
        Collection<Column> columns = entityFields.values();
        for (Column column : columns) {
            build.append(column.getValue()).append(" ").append(column.getType());
            if (column.getLength() > 0) {
                build.append("(").append(column.getLength()).append(")");
            }
            if (column.isPrimary()) {
                build.append(" PRIMARY KEY");
            }
            if (column.isIncrement()) {
                build.append(" AUTOINCREMENT");
            }
            if (!column.isNull()) {
                build.append(" NOT NULL");
            }
            build.append(",");
        }
        build.delete(build.length() - 1, build.length());
        return build.toString();
    }

    private Set<Column> filterColumns(String... columns) {
        Set<Column> columnSet = new HashSet<Column>();
        if (columns == null || columns.length == 0) {
            columnSet.addAll(entityFields.values());
        } else {
            for (String column : columns) {
                String c2 = CommonUtil.toHump(column);
                Column col = entityFields.get(c2);
                if (col == null) {
                    continue;
                }
                columnSet.add(col);
            }
        }
        return columnSet;
    }

    /**
     * 生成列名
     *
     * @param columns 要生成的列名,忽略生成全部
     * @return 列名
     */
    private String getColumn(String... columns) {
        StringBuilder build = new StringBuilder();

        Set<Column> colSet = filterColumns(columns);
        for (Column col : colSet) {
            build.append(col.getValue()).append(",");
        }
        build.delete(build.length() - 1, build.length());
        return build.toString();
    }

    private String getFunColumn(String... columns) {
        StringBuilder build = new StringBuilder();

        for (String col : columns) {
            build.append(col).append(",");
        }
        build.delete(build.length() - 1, build.length());
        return build.toString();
    }

    public String getTableName() {
        return tableName;
    }

    public String createTable() {
        StringBuilder sql = new StringBuilder("CREATE TABLE ");
        sql.append(tableName).append(" (");
        sql.append(getColumnDDL());
        sql.append(")");
        return sql.toString();
    }

    public String dropTable() {
        StringBuilder sql = new StringBuilder("DROP TABLE ");
        sql.append(tableName);
        return sql.toString();
    }

    /**
     * 生成 select 语句
     */
    public String selectSql(String condition, String sort) {
        StringBuilder sql = new StringBuilder("");
        sql.append("SELECT ").append(getColumn()).append(" FROM ").append(tableName);
        sql.append(where(condition));
        sql.append(order(sort));
        return sql.toString();
    }

    /**
     * 生成自定义 select 语句,与Bean声明一致
     */
    public String selectCustomSql(String[] columns, String condition, String sort) {
        StringBuilder sql = new StringBuilder("");
        sql.append("SELECT ").append(getColumn(columns)).append(" FROM ").append(tableName);
        sql.append(where(condition));
        sql.append(order(sort));
        return sql.toString();
    }

    @Override
    public String selectFunSql(String[] columns, String condition) {
        StringBuilder sql = new StringBuilder();
        sql.append("SELECT ").append(getFunColumn(columns)).append(" FROM ").append(tableName);
        sql.append(where(condition));
        return sql.toString();
    }

    /**
     * 生成 select 分页语句
     */
    public String selectSqlForPager(int pageNumber, int pageSize, String condition, String sort) {
        StringBuilder sql = new StringBuilder();
        sql.append("SELECT ").append(getColumn()).append(" FROM ").append(tableName);
        sql.append(where(condition));
        sql.append(order(sort));
        sql.append(limit(pageNumber, pageSize));
        return sql.toString();
    }


    private String where(String condition) {
        if (!ObjectUtil.isEmpty(condition)) {
            return " WHERE " + condition;
        }
        return "";
    }

    private String order(String sort) {
        if (!ObjectUtil.isEmpty(sort)) {
            return " ORDER BY " + sort;
        }
        return "";
    }

    /**
     * select * from 表名 where 条件 order by 排序 limit 开始位置, 结束位置
     */
    private String limit(int pageNumber, int pageSize) {
        int ps = (pageNumber - 1) * pageSize;
        StringBuilder sql = new StringBuilder();
        sql.append(" LIMIT ").append(ps).append(", ").append(pageSize);
        return sql.toString();
    }

    /**
     * 生成 insert 语句
     */
    public String insertSql(Collection<String> fieldNames) {
        return null;
    }

    /**
     * 生成 delete 语句
     */
    public String deleteSql(String condition) {
        return null;
    }

    /**
     * 生成 update 语句
     */
    public String updateSql(Map<String, Object> fieldMap, String condition) {
        return null;
    }

    public ContentValues getContentValues(T t) {
        return getContentValues(t, null);
    }

    public ContentValues getContentValues(T t, String[] columns) {
        if (entityFields == null || entityFields.isEmpty()) {
            return null;
        }
        ContentValues cv = new ContentValues();
        Set<Column> colSet = filterColumns(columns);
        for (Column col : colSet) {
            String name = col.getValue();
            String c2 = CommonUtil.toHump(name);
            Object val = BeanUtil.getFieldValue(t, c2);
            if (val == null || ("id".equals(name) && ((Long) val) == 0L)) {
                continue;
            }
            cv.put(name, ObjectUtil.toString(val));
        }
        return cv;
    }
}
